﻿using System;
using System.Reflection;
using System.Linq;

namespace SharpPad.Forms
{
    public class AssemblyReference : IComparable
    {
        public String Name { get; set; }
        public String Token { get; set; }
        public String Version { get; set; }
        public String Path { get; set; }
        private int AssemblyHash { get; set; }

        public AssemblyReference(Assembly assembly)
        {
            var token = assembly.GetName().GetPublicKeyToken();
            Name = assembly.GetName().Name;
            Token = token != null && token.Length > 0 ? token.Select(x => x.ToString("x2")).Aggregate((acc, next) => acc + next) : null ; 
            Version = assembly.GetName().Version.ToString();
            Path = assembly.Location;
            AssemblyHash = assembly.GetHashCode();
        }

        public override bool Equals(object obj)
        {
            //       
            // See the full list of guidelines at
            //   http://go.microsoft.com/fwlink/?LinkID=85237  
            // and also the guidance for operator== at
            //   http://go.microsoft.com/fwlink/?LinkId=85238
            //

            if (obj == null || GetType() != obj.GetType())
            {
                return false;
            }

            var o = (AssemblyReference)obj ;

            return (
                       Name == o.Name &&
                       Token == o.Token &&
                       Version == o.Version &&
                       Path == o.Path
                   );
        }

        public override int GetHashCode()
        {
            return AssemblyHash;
        }

        /// <summary>
        /// Compares the current instance with another object of the same type and returns
        ///  an integer that indicates whether the current instance precedes, follows, or
        ///  occurs in the same position in the sort order as the other object.
        /// </summary>
        /// <returns>
        /// A value that indicates the relative order of the objects being compared. The
        ///  return value has these meanings: Value Meaning Less than zero This instance
        ///  is less than <paramref name="obj"/>. Zero This instance is equal to <paramref name="obj"/>.
        ///  Greater than zero This instance is greater than <paramref name="obj"/>. 
        /// </returns>
        /// <param name="obj">An object to compare with this instance. </param><exception cref="T:System.ArgumentException"><paramref name="obj"/> is not the same type as this instance. </exception><filterpriority>2</filterpriority>
        public int CompareTo(object obj)
        {
            return this == obj ? 0 : String.Compare(Name, ((AssemblyReference)obj).Name, StringComparison.Ordinal);
        }
    }
}